Kubernetes 控制器主要目的是協調(Reconcile)某個 API 資源的狀態,從實際狀態轉換為期望狀態,換句話說,在 Kubernetes API 資源上的說法,就是讓 API 資源的.status
狀態,達到.spec
所定義內容。而為了達到這點,控制器會透過 client-go 一直監視這兩種狀態的變化,並在發現變化時,觸發協調邏輯的循環,以更改當前狀態所需的任何操作,並使其往資源的預期狀態進展。Kubernetes 為了實現這樣機制,在 API 提供了一組 List 與 Watch 方法,用於監視任何 API 資源的事件。而自定義控制器就是以 client-go 操作這些 API 方法,監視其主要的自定義資源與其他任何相關的資源。
舉例,想要實現管理 TensorFlow 分散式訓練的控制器。這個控制器不僅要監視 TensorFlowJob(這是自定義資源) 物件的變化,而必須響應 Pod 事件,以確保 Pod 能再發生狀況時,處理對應狀況。當然這種追蹤 API 資源之間關聯的機制,也能利用 Kubernetes 的 Owner references 機制達成。這機制允許控制器在任何 API 資源上,設定資源的父子關析(如 Deployment 與 Pod 關聯這樣),而當子資源事件發生時,就能反應給控制器,以知道哪個 TensorFlowJob 物件已受到影響,這時再由控制器的檢查與協調循環,來解決狀態的變化。
但講這麼多,一個控制器內部究竟是如何運作呢?今天就是要來聊聊這個內容。
這部分將解釋 Kubernetes 自定義控制器運作流程,如下圖所示。一個自定義控制器是由 client-go 中的幾個主要功能實現,並結合自己實現的邏輯來達成。因此在開發前,必須先理解這些名詞與功能是做什麼用的。
(圖片擷取自:Kubernetes sample-controller)
從架構圖來看,主要的 client-go 會有以下三者處理:
namespace/name
。而除了上面 client-go 元件外,在開發一個自定義控制器時,還會有以下幾個元件會被使用到:
onAdd()
、onUpdate()
與onDelete()
。當 Informer 收到 API 資源物件事件時,就會呼叫這些函式,這時自定義控制器就能在函式中處理接下來事情。今天理解了自定義控制器使用到的元件,以及其運作方式,從中可以發現 Kubernetes client-go 幾乎是整個控制器的核心,許多功能實現都是圍繞著該函式庫。明天將部署 sample-controller 到 Minikube 上,以釐清一些功能運作流程,這些知識與觀念將用於後續範例開發中。
雖然 Kubernetes 控制器看起來似乎很複雜,事實上簡化來看,大概也就長這個樣子: